package meatslope2.gameengine.gameobjects;

import java.util.ArrayList;
import java.util.List;

import meatslope2.constants.BitmapConstants;
import meatslope2.gameengine.gameobjects.model.DrawableGameObject;
import meatslope2.gameengine.gameobjects.model.Sprite;
import meatslope2.gameengine.helpers.Utils;
import meatslope2.gameengine.primatives.LineSegment;

/**
 * A bunch of these are generated in @link{TileConstants}, they can be looked up by their index (no sense in creating a bunch of
 * dup tiles)
 * @author Mitchell Thelen
 *
 */
public class Tile extends DrawableGameObject
{
	// ===========================================================
	// Members
	// ===========================================================
	
	private final int index;
	private final LineSegment[] lineSegments;
	
	// ===========================================================
	// Getters/Setters
	// ===========================================================
	
	public LineSegment[] getLineSegments()
	{
		return this.lineSegments;
	}
	
	public int index()
	{
		return this.index;
	}
	
	// ===========================================================
	// Constructors
	// ===========================================================
	
	private Tile(Sprite sprite, LineSegment[] lineSegments, int index)
	{
		super(sprite, BitmapConstants.TILE_WIDTH, BitmapConstants.TILE_HEIGHT);
		
		this.lineSegments = lineSegments;
		this.index = index;
	}
	
	/**
	 * Builder pattern for tile generation
	 * @author Mitchell Thelen
	 *
	 */
	public static final class Builder 
	{
		// ===========================================================
		// Members
		// ===========================================================
		
		private Sprite sprite;
		private int index;
		private List<LineSegment> lineSegments;
		
		// ===========================================================
		// Getter/Setter
		// ===========================================================
		
		public Builder setIndex(int index)
		{
			assert index >= 0;
			
			this.index = index;
			return this;
		}
		
		public final Builder setSprite(Sprite sprite)
		{
			this.sprite = sprite;
			return this;
		}
		
		public final Builder addLineSegment(LineSegment lineSegment)
		{
			this.lineSegments.add(lineSegment);
			return this;
		}
		
		// ===========================================================
		// Constructors
		// ===========================================================
		
		public Builder()
		{
			reset();
		}
		
		// ===========================================================
		// Constructors
		// ===========================================================
		
		private final void reset()
		{
			sprite = null;
			index = -1;
			lineSegments = new ArrayList<LineSegment>();
		}
		
		public final Tile build()
		{
			assert this.sprite == null : "Tile's sprite has not been set!";
			assert this.index != -1 : "Tile's index has not been set!";
			
			//Create our tile
			LineSegment[] lineSegmentArray = Utils.toArray(this.lineSegments, new LineSegment[this.lineSegments.size()]);
			Tile newTile = new Tile(this.sprite, lineSegmentArray, this.index);
			
			//Cleanup
			reset();
			
			return newTile;
		}
	}
}
